using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SqlTools.CodeGenerator.Data;
using schema = SqlTools.SchemaReader;

namespace SqlTools.CodeGenerator.UI.Controls
{
	public partial class ForeignKeyTablePropertyEditor : UserControl
	{
		protected Project _project;
		protected ForeignKeyTableProperty _property = null;
		protected Table _currentTable = null;

		protected bool _loading = false;

		public ForeignKeyTablePropertyEditor()
		{
			InitializeComponent();
		}

		public Project Project
		{
			get { return _project; }
			set 
			{
				_project = value;

				_loading = true;

				cboReferenceTable.Items.Clear();
				cboReferenceTable.DisplayMember = "Name";
				foreach ( Table table in _project.Tables )
				{
					cboReferenceTable.Items.Add(table);
				}

				cboForeignTable.Items.Clear();
				cboForeignTable.DisplayMember = "Name";
				foreach (Table table in _project.Tables )
				{
					cboForeignTable.Items.Add(table);
				}

				_loading = false;
			}
		}

		public ForeignKeyTableProperty Property
		{
			get { return _property; }
			set 
			{ 
				_property = value;

				_loading = true;

				if ( _property != null )
				{
					if ( _property.ReferenceTable != null )
					{
						cboReferenceTable.SelectedItem = _property.ReferenceTable;

						cboReferenceRetrieveMethod.Items.Clear();
						cboReferenceRetrieveMethod.DisplayMember = "MethodName";

						foreach ( Method method in _property.ReferenceTable.Methods )
						{
							cboReferenceRetrieveMethod.Items.Add(method);
						}

						cboReferenceColumn.SelectedItem = _property.ReferenceColumnName;

						cboReferenceRetrieveMethod.SelectedItem = _property.ReferenceRetrieve;
					}

					txtRefObjectFieldName.Text = _property.ReferenceObjectFieldName;
					txtRefObjectPropertyName.Text = _property.ReferenceObjectPropertyName;
					txtReferenceFieldName.Text = _property.ReferenceFieldName;
					txtReferencePropertyName.Text = _property.ReferencePropertyName;

					if ( _property.ForeignKeyTable != null )
					{
						cboForeignTable.SelectedItem = _property.ForeignKeyTable;

						cboForeignRetrieveMethod.Items.Clear();
						cboForeignRetrieveMethod.DisplayMember = "MethodName";

						foreach ( Method method in _property.ForeignKeyTable.Methods )
						{
							cboForeignRetrieveMethod.Items.Add(method);
						}

						cboForeignColumn.SelectedItem = _property.ForeignKeyColumnName;

						cboForeignRetrieveMethod.SelectedItem = _property.ForeignRetrieve;
					}

					txtForeignObjectFieldName.Text = _property.ForeignObjectFieldName;
					txtForeignObjectPropertyName.Text = _property.ForeignObjectPropertyName;
				}

				_loading = false;
			}
		}

		public Table CurrentTable
		{
			get { return _currentTable; }
			set 
			{ 
				_currentTable = value;

				_loading = true;

				if ( _currentTable == null )
				{
					ToggleForeignSelection(true);
					ToggleReferenceSelection(true);
				}
				else
				{
					if ( _property != null )
					{
						if ( _property.ReferenceTable == null || _property.ForeignKeyTable == null )
						{
							if ( _property.ReferenceTable == null )
							{
								if ( _property.ForeignKeyTable != null && _property.ForeignKeyTable == _currentTable )
								{
									grpForeignKey.Text = "Foreign Table (this)";
								}
								else
								{
									grpForeignKey.Text = "Foreign Table";
								}

								ToggleReferenceSelection(true);
							}
							else
							{
								ToggleReferenceSelection(false);
							}

							if ( _property.ForeignKeyTable == null )
							{
								if ( _property.ReferenceTable != null && _property.ReferenceTable == _currentTable )
								{
									grpRefTable.Text = "Reference Table (this)";
								}
								else
								{
									grpRefTable.Text = "Reference Table";
								}

								ToggleForeignSelection(true);
							}
							else
							{
								ToggleForeignSelection(true);
							}
						}
						else
						{
							ToggleForeignSelection(false);
							ToggleReferenceSelection(false);

							if ( _property.ReferenceTable == _currentTable )
							{
								grpRefTable.Text = "Reference Table (this)";
								grpForeignKey.Text = "Foreign Table";
							}
							else
							{
								grpRefTable.Text = "Reference Table";
								grpForeignKey.Text = "Foreign Table (this)";
							}
						}
					}
				}

				_loading = false;
			}
		}

		protected void ToggleReferenceSelection(bool editable)
		{
			cboReferenceColumn.Enabled = editable;
			cboReferenceTable.Enabled = editable;
		}

		protected void ToggleForeignSelection(bool editable)
		{
			cboForeignColumn.Enabled = editable;
			cboForeignTable.Enabled = editable;
		}

		#region Reference Table Event Handlers
		private void txtRefObjectFieldName_TextChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			_property.ReferenceObjectFieldName = txtRefObjectFieldName.Text;
		}

		private void txtRefObjectPropertyName_TextChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			_property.ReferenceObjectPropertyName = txtRefObjectPropertyName.Text;
		}

		private void txtReferenceFieldName_TextChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			_property.ReferenceFieldName = txtReferenceFieldName.Text;
		}

		private void txtReferencePropertyName_TextChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			_property.ReferencePropertyName = txtReferencePropertyName.Text;
		}

		private void cboReferenceRetrieveMethod_SelectedIndexChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			if ( cboReferenceRetrieveMethod.SelectedItem != null )
			{
				_property.ReferenceRetrieve = cboReferenceRetrieveMethod.SelectedItem as Method;
			}
			else
			{
				_property.ReferenceRetrieve = null;
			}
		}

		private void cboReferenceTable_SelectedIndexChanged(object sender, EventArgs e)
		{
			cboReferenceColumn.Items.Clear();

			cboReferenceRetrieveMethod.Items.Clear();
			cboReferenceRetrieveMethod.DisplayMember = "MethodName";

			if ( cboReferenceTable.SelectedItem != null )
			{
				Table dtable = cboReferenceTable.SelectedItem as Table;
				schema.Table table = _project.Database.Tables[dtable.TableName];

				foreach ( schema.Column column in table.Columns )
				{
					cboReferenceColumn.Items.Add(column.Name);
				}

				_property.ReferenceTable = dtable;

				if ( dtable != null )
				{
					foreach ( Method method in dtable.Methods.GetMethodsByType(MethodType.SelectSingle) )
					{
						cboReferenceRetrieveMethod.Items.Add(method);
					}
				}
			}
			else
			{
				if ( _loading ) return;

				_property.ReferenceTable = null;
			}
		}

		private void cboReferenceColumn_SelectedIndexChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			if ( cboReferenceColumn.SelectedItem != null )
			{
				_property.ReferenceColumnName = ( (schema.Column)cboReferenceColumn.SelectedItem ).Name;
			}
			else
			{
				_property.ReferenceColumnName = "";
			}
		}

		#endregion

		#region Foreign Table Event Handlers
		private void txtForeignObjectFieldName_TextChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			_property.ForeignObjectFieldName = txtForeignObjectFieldName.Text;
		}

		private void txtForeignObjectPropertyName_TextChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			_property.ForeignObjectPropertyName = txtForeignObjectPropertyName.Text;
		}

		private void cboForeignRetrieveMethod_SelectedIndexChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			if ( cboForeignRetrieveMethod.SelectedItem != null )
			{
				_property.ForeignRetrieve = cboForeignRetrieveMethod.SelectedItem as Method;
			}
			else
			{
				_property.ForeignRetrieve = null;
			}
		}

		private void cboForeignTable_SelectedIndexChanged(object sender, EventArgs e)
		{
			cboForeignColumn.Items.Clear();
			

			cboForeignRetrieveMethod.Items.Clear();
			cboForeignRetrieveMethod.DisplayMember = "MethodName";

			if ( cboForeignTable.SelectedItem != null )
			{
				Table dtable = cboForeignTable.SelectedItem as Table;
				schema.Table table = _project.Database.Tables[dtable.TableName];

				foreach ( schema.Column column in table.Columns )
				{
					cboForeignColumn.Items.Add(column.Name);
				}

				_property.ForeignKeyTable = dtable;

				if ( dtable != null )
				{
					foreach ( Method method in dtable.Methods.GetMethodsByType(MethodType.SelectSingle) )
					{
						cboForeignRetrieveMethod.Items.Add(method);
					}
				}
			}
			else
			{
				if ( _loading ) return;

				_property.ForeignKeyTable = null;
			}
		}

		private void cboForeignColumn_SelectedIndexChanged(object sender, EventArgs e)
		{
			if ( _loading ) return;

			if ( cboForeignColumn.SelectedItem != null )
			{
				_property.ForeignKeyColumnName = ( (schema.Column)cboForeignColumn.SelectedItem ).Name;
			}
			else
			{
				_property.ForeignKeyColumnName = "";
			}
		}
		#endregion
	}
}
